Skip to content

Conversation

@eenblam
Copy link
Contributor

@eenblam eenblam commented Nov 18, 2025

This adds a configurable collection of Authorizer callbacks for downstream users to assign to. Presently, this enables end users to define authZ callbacks for workflows defined upstream in orchestrator-core. This could also be extended to include default Authorizers for user-defined workflows.

Marking as draft because this change should also update the docs, but I want some initial feedback on the approach before I do that. I've already created some comments explaining my approach, but I'm very open to adjusting per feedback.

Closes #1066

_authorizers = Authorizers()


def get_authorizers() -> Authorizers:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using this to reduce footgun opportunities since this is security-focused. On the other hand, it doesn't match how we handle app_settings, so I'm open to not going this route if folks have strong opinions about it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the this need to be registered from the app the same way we have app.register_authorization

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree that this doesn't belong to the settings class.

What I do think may cause confusion for end users is the AuthManager class which is defined in the oauth2_lib library:

class AuthManager:
    """Manages the authentication and authorization mechanisms for the application.

    This manager class orchestrates authentication and authorization, utilizing OpenID Connect (OIDC) and
    Open Policy Agent (OPA) respectively. It serves as a central hub for user authentication states and
    authorization policies. If defaults are insufficient, users can register alternatives or customize existing ones.
    ...."""

An instance of that class is created in the OrchestratorCore(FastAPI) class, and in downstream apps the authn/authz instances can be overridden like so:

    app.register_authentication(surf_authn)
    app.register_authorization(surf_authz)
    app.register_graphql_authorization(surf_graphql_authz)

The AuthManager's docstring suggests that it manages all authn/authz, but obviously this only holds for the API - the workflow authz is specifically for the Worker (which, in case of the threadpool executor, is running in the same process; but for the celery executor it will be separate).

I'm not suggesting we should make the Authorizers part of the AuthManager, maybe we can just name/document things well enough to avoid confusion. And perhaps tweak the AuthManager's docstring a little bit to say it's for the API.

Copy link
Contributor

@tjeerddie tjeerddie Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auth manager isn't specifically for the API, I would have used it in our version for the authorize_callback if we could use an async function. I'm also not saying that they need to be included in the AuthManager within oauth2-lib, since its orchestrator specific.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the workflow authz is specifically for the Worker

Just to clarify - the API endpoints for creating and resuming processes do check these callbacks, along with a couple other REST and GraphQL endpoints. I'm not actually aware of the worker running these checks; by checking in the request handler, we can prevent the workflow from ever making it to the queue if the process shouldn't be queued/re-queued.

I originally considered adding OrchestratorCore.register_internal_authorization_callbacks(authorize_callback=None, retry_auth_callback=None). I decided against it at the time since the process of checking this info seems kinda independent of the app from the perspective of building orch-core. Something-something loose coupling. That said, I can see it being more intuitive for the end user to configure it as part of the application.

Should I add it to OrchestratorCore class, or just continue with the current approach while making it clear that AuthManager is a separate thing in the docs?

expose_settings("oauth2lib_settings", oauth2lib_settings) # type: ignore


class Authorizers:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These could have gone into AppSettings, but it seemed like

  1. it would be weird printing these out when settings are exposed
  2. (more importantly) it would suggest to users that this can be set by environment variable

So I opted to separate them out. Feedback/direction appreciated.

@eenblam eenblam force-pushed the 1066-feature-add-optional-global-authorize_callback-for-rbac branch from b185180 to 1291dd9 Compare November 18, 2025 23:23
@codspeed-hq
Copy link

codspeed-hq bot commented Nov 18, 2025

CodSpeed Performance Report

Merging #1215 will not alter performance

Comparing 1066-feature-add-optional-global-authorize_callback-for-rbac (1291dd9) with main (4f98b5b)

Summary

✅ 13 untouched

@sentry
Copy link

sentry bot commented Nov 18, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 79.34%. Comparing base (eee770b) to head (1291dd9).
⚠️ Report is 22 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1215      +/-   ##
==========================================
- Coverage   79.58%   79.34%   -0.25%     
==========================================
  Files         272      273       +1     
  Lines       13196    13365     +169     
  Branches     1295     1311      +16     
==========================================
+ Hits        10502    10604     +102     
- Misses       2414     2480      +66     
- Partials      280      281       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Mark90 Mark90 requested a review from tjeerddie November 19, 2025 11:40
@Mark90 Mark90 marked this pull request as draft November 19, 2025 11:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Add optional global authorize_callback for RBAC

4 participants